package com.ruoyi.xdata.controller;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;

import com.ruoyi.xdata.domain.XdataClient;
import com.ruoyi.xdata.domain.XdataModel;
import com.ruoyi.xdata.domain.XdataPipe;
import com.ruoyi.xdata.domain.XdataVo;
import com.ruoyi.xdata.service.IXdataClientService;
import com.ruoyi.xdata.service.IXdataModelService;
import com.ruoyi.xdata.service.IXdataPipeService;
import com.ruoyi.xdata.service.IXdataService;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.util.DbUtil;

/**
 * 数据Controller
 * 
 * @author yepanpan
 * @date 2020-12-29
 */
@RestController
@RequestMapping("/xdata/data")
public class XdataDataController extends BaseController
{
	@Autowired	 
    private DataSource dataSource; 
    @Autowired
    private IXdataService xdataService;
    @Autowired
    private IXdataClientService xdataClientService;
    @Autowired
    private IXdataPipeService xdataPipeService;
    @Autowired
    private IXdataModelService xdataModelService;
    @Autowired
    private RedisCache redisCache;
         
    /**
     * 查询查询数据
     */
    @GetMapping("/list")
    public TableDataInfo list(XdataVo data)
    {    	
    	AjaxResult ret = check(data, "R");
    	int code = Integer.parseInt(ret.get(AjaxResult.CODE_TAG).toString());
    	if(code != HttpStatus.SUCCESS) {
    		TableDataInfo td = new TableDataInfo();
    		td.setCode(code);
    		td.setMsg(ret.get(AjaxResult.MSG_TAG).toString());
    		return td;
    	}
    	
    	XdataPipe pipe = getPipe(data, "R");
    	if(pipe == null) {
    		TableDataInfo td = new TableDataInfo();
    		td.setCode(code);
    		td.setMsg("模型不存在或者您没有权限");
    		return td;
    	}
    	    	
        startPage();
        DbUtil read;
		try {
			read = new DbUtil(dataSource.getConnection());
			Map<String, Object> params = data.getParams();
			params.put("offset", data.getOffset());
			params.put("limit", data.getLimit());
			params.put("last", data.getLast());
			
			List<Map> list = read.query(pipe.getReadSql(), params);// xdataService.selectList(data);
	        return getDataTable(list);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        return new TableDataInfo();
    }

    /**
     * 获取数据详细信息
     */
    @GetMapping(value = "/find")
    public AjaxResult find(XdataVo data)
    {
    	AjaxResult ret = check(data, "R");
    	int code = Integer.parseInt(ret.get(AjaxResult.CODE_TAG).toString());
    	if(code != HttpStatus.SUCCESS) {
    		return ret;
    	}
    	
        return AjaxResult.success(xdataService.findData(data));
    }


    /**
     * 删除数据
     */
	@DeleteMapping
    public AjaxResult remove(XdataVo data)
    {
    	AjaxResult ret = check(data, "W");
    	int code = Integer.parseInt(ret.get(AjaxResult.CODE_TAG).toString());
    	if(code != HttpStatus.SUCCESS) {
    		return ret;
    	}
        return toAjax(xdataService.deleteData(data));
    }
    

    /**
     * 获取令牌
     */
    @PostMapping("token")
    public AjaxResult token(@RequestBody XdataClient xdataClient)
    {
    	xdataClient.setStatus("1");
    	List<XdataClient> list = xdataClientService.selectXdataClientList(xdataClient);
    	if(list == null || list.size() != 1) return AjaxResult.error("应用信息不存在");
    	String token = UUID.fastUUID().toString();
    	redisCache.setCacheMapValue("xdata_token", token, list.get(0));
        return AjaxResult.success(token);
    }
    
    /**
     * 新增数据
     */
    @PostMapping("save")
    public AjaxResult save(@RequestBody XdataVo data)
    {
    	return push(data);
    }

    /**
     * 新增数据
     */
    @PostMapping("push")
    public AjaxResult push(@RequestBody XdataVo data)
    {
    	AjaxResult ret = check(data, "W");
    	int code = Integer.parseInt(ret.get(AjaxResult.CODE_TAG).toString());
    	if(code != HttpStatus.SUCCESS) {
    		return ret;
    	}
    	
    	XdataPipe pipe = getPipe(data, "W");
    	if(pipe == null) {
    		return AjaxResult.error("模型不存在或者您没有权限");
    	}
    	
		DbUtil writer;
		try {
			writer = new DbUtil(dataSource.getConnection());
	    	int rc = 0;
	    	List<Map<String, Object>> rows = data.getRows();
	    	if(rows == null) {
	    		rows = new ArrayList<>();
	    		rows.add(data.getData());	    		
	    	}
	    	for(Map<String, Object> row: rows) {
	    		if(writer.find(pipe.getExistSql(), row) == null) {
		    		rc += writer.exec(pipe.getInsertSql(), row);
				}else {
					rc += writer.exec(pipe.getUpdateSql(), row);
				}
	    	}
	    	
	        return toAjax(rc);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	return AjaxResult.error("同步数据失败");
    }
    
    /**
     * 验证权限
     * @param data
     * @param mode
     * @return
     */
    private AjaxResult check(XdataVo data, String mode) {
    	String token = data.getToken();
    	if(StringUtils.isEmpty(data.getTable())) {
    		return AjaxResult.error(504, "数据表不能为空");
    	}
    	
    	if(StringUtils.isEmpty(token)) {
    		return AjaxResult.error(401, "令牌不能为空");
    	}
    	
    	XdataClient client = redisCache.getCacheMapValue("xdata_token", token);
    	if(client == null) {
    		return AjaxResult.error(401, "令牌不存在或者已过期");
    	}
    		
    	
    	return AjaxResult.success();
    }
    
    /**
     * 查询管道信息
     * @param data
     * @param mode
     * @return
     */
    private XdataPipe getPipe(XdataVo data, String mode) {

    	XdataModel model = xdataModelService.selectXdataModelByTable(data.getTable());
    	if(model == null) {
    		return null;
    	}    
    	
    	XdataClient client = redisCache.getCacheMapValue("xdata_token", data.getToken());
    	XdataPipe pc = new XdataPipe();
    	pc.setClientId(client.getId());
    	pc.setModelId(model.getId());
    	pc.setMode(mode.toLowerCase());
    	
    	List<XdataPipe> ps = xdataPipeService.selectXdataPipeList(pc);
    	if(ps == null || ps.size() == 0) {
    		return null;
    	}   
    	return ps.get(0);
    }
}
